package com.have.haveblog.security.utils;

import com.have.blog.base.constant.BaseSysConstant;
import io.jsonwebtoken.*;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.userdetails.UserDetails;

import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
import java.security.Key;
import java.util.Date;

@Slf4j
public class JwtTokenUtil {

    private Claims parseJwt(String token, String base64Security){
        try {
            Claims claims = Jwts.parser()
                    .setSigningKey(DatatypeConverter.parseBase64Binary(base64Security))
                    .parseClaimsJws(token).getBody();
            return claims;
        } catch (Exception e) {
           return null;
        }
    }
    /**
     *
     * @param username       账号名
     * @param adminUid       账号UID
     * @param audience       这个Jwt的接受对象
     * @param issuer         这个Jwt的签发主题
     * @param TTLMillis      jwt的有效时间
     * @param base64Security 加密方式
     * @return
     */
    public String generateJwtToken(String username, String adminUid,
                                    String audience, String issuer, long TTLMillis, String base64Security) {
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
        long nowMillis = System.currentTimeMillis();
        Date now = new Date(nowMillis);
        // 生成签名密钥
        byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary(base64Security);
        Key signingKey = new SecretKeySpec(apiKeySecretBytes, signatureAlgorithm.getJcaName());
        JwtBuilder jwtBuilder = Jwts.builder()
                .setHeaderParam("typ", "JWT")
                .claim(BaseSysConstant.ADMIN_UID, adminUid)
                .claim(BaseSysConstant.CREATE_TIME, now)
                .setSubject(username)
                .setIssuer(issuer)
                .setAudience(audience)
                .signWith(signatureAlgorithm, signingKey);
        if (TTLMillis >= 0) {
            long exMillis = nowMillis + TTLMillis;
            Date exp = new Date(exMillis);
            jwtBuilder.setExpiration(exp).setNotBefore(now);
        }
        return  jwtBuilder.compact();
    }

    /**
     * 通过token获取用户名
     * @param token
     * @param base64Security
     * @return
     */
    public String getUsername(String token, String base64Security) {
        Claims claims = parseJwt(token, base64Security);
        if (claims != null) {
            return claims.getSubject();
        }
        return "";
    }

    public String getAdminUid(String token, String base64Security) {
        Claims claims = parseJwt(token, base64Security);
        if (claims != null) {
            return claims.get(BaseSysConstant.ADMIN_UID, String.class);
        }
        return "";
    }

    /**
     * 判断token是否已过期
     * @param token
     * @param base64Security
     * @return
     */
    public boolean isExpiration(String token, String base64Security) {
        Claims claims = parseJwt(token, base64Security);
        return claims == null || claims.getExpiration().before(new Date());
    }

    /**
     * 校验token
     * @return
     */
    public boolean validateToken(String token, UserDetails userDetails, String base64Security) {
        String username = getUsername(token, base64Security);
        boolean expiration = isExpiration(token, base64Security);
        return username.equals(userDetails.getUsername()) && !expiration;
    }

    public static void main(String[] args) {
        String token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhZG1pblVpZCI6Ijc2MjE3NDZjYWE5M2NlNjA1ZTJkZTcxNDNhMzc4N2I1IiwiY3JlYXRlVGltZSI6MTYyMDczNzgwNjQxNiwic3ViIjoibW9ndTIwMTgiLCJpc3MiOiJoYXZlIiwiYXVkIjoiY2xpZW50IiwiZXhwIjoxNjIwNzM3ODY2LCJuYmYiOjE2MjA3Mzc4MDZ9.9hsCwH9iWntXR-VpfNehs7utADcQHawxhThqbsA2nyo";
        JwtTokenUtil jwtTokenUtil = new JwtTokenUtil();
        String username = jwtTokenUtil.getUsername(token, "kosajdfoipahefoipasdoiuyoiah");
        System.out.println(username);

    }
}
